package com.atcc.demo.util;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description 日期基础操作工具类
 * @Author wangzhenwei
 * @Date 2019/08/14
 **/
public class DateUtils {
    public static Date INITIAL_DATE = new Date(0L);
    public static Date FAR_FAR_AWAY = new Date(System.currentTimeMillis() + 31536000000000L);
    public static ThreadLocalDateFormat HH_MM = new ThreadLocalDateFormat("HH:mm");
    public static ThreadLocalDateFormat HH_MM_SS = new ThreadLocalDateFormat("HH:mm:ss");
    public static ThreadLocalDateFormat MM_DD_YYYY_SLASH = new ThreadLocalDateFormat("MM/dd/yyyy");
    public static ThreadLocalDateFormat YYYY_MM_DD = new ThreadLocalDateFormat("yyyy-MM-dd");
    public static ThreadLocalDateFormat MM_DD = new ThreadLocalDateFormat("MM-dd");
    public static ThreadLocalDateFormat YYYY_MM_DD_HH_MM = new ThreadLocalDateFormat("yyyy-MM-dd HH:mm");
    public static ThreadLocalDateFormat YYYY_MM_DD_HH_MM_SS = new ThreadLocalDateFormat("yyyy-MM-dd HH:mm:ss");
    public static ThreadLocalDateFormat MM_DD_HH_MM_SS = new ThreadLocalDateFormat("MM-dd HH:mm:ss");
    public static ThreadLocalDateFormat YYYY_NIAN_MM_YUE = new ThreadLocalDateFormat("yyyy年MM月");
    public static ThreadLocalDateFormat YYYYMM = new ThreadLocalDateFormat("yyyyMM");
    public static ThreadLocalDateFormat YYYY_MM = new ThreadLocalDateFormat("yyyy-MM");
    public static ThreadLocalDateFormat YYYYMMDD = new ThreadLocalDateFormat("yyyyMMdd");
    public static ThreadLocalDateFormat YYYYMMDDHH = new ThreadLocalDateFormat("yyyyMMddHH");
    public static ThreadLocalDateFormat YYYYMMDDHHMM = new ThreadLocalDateFormat("yyyyMMddHHmm");
    public static ThreadLocalDateFormat YYYYMMDDHHMMSS = new ThreadLocalDateFormat("yyyyMMddHHmmss");
    public static ThreadLocalDateFormat YYYYMMDDHHMMSSSSS = new ThreadLocalDateFormat("yyyyMMddHHmmssSSS");

    public static Date getNow() {
        return new Date();
    }

    public static Date getInitTime() {
        Date date = new Date();
        date.setTime(0);
        return date;
    }

    /**
     * 返回当前天时间（0 点 0 分 0 秒）
     *
     * @return
     */
    public static Date getDayBegin() {
        return getDayBegin(new Date());
    }

    /**
     * 返回当前天时间（23 点 59 分 59 秒）
     *
     * @return
     */
    public static Date getDayEnd() {
        return getDayEnd(new Date());
    }

    /**
     * 某一天0点0分0秒的时间
     *
     * @param date
     * @return
     */
    public static Date getDayBegin(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 某一天23点59分59秒的时间
     *
     * @param date
     * @return
     */
    public static Date getDayEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 格式时间
     *
     * @param date 日期
     * @return yyyy-MM-dd
     */
    public static String formatDate(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    public static String formatDate(Date date, String pattern) {
        ThreadLocalDateFormat sdf = new ThreadLocalDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 格式化日期字符串为日期对象
     *
     * @param dateStr
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date parseDateStr(String dateStr, String pattern) throws ParseException {
        if (dateStr == null)
            return null;
        ThreadLocalDateFormat sdf = new ThreadLocalDateFormat(pattern);
        return sdf.parse(dateStr);
    }

    /**
     * 字符串转换为Date对象，自动匹配日期格式
     *
     * @param dateStr 日期字符串
     * @return Date
     */
    public static Date stringToDate(String dateStr) {
        return stringToDate(dateStr, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 把字符串转换为Date类型
     *
     * @param strDate 日期字符串
     * @param pattern 日期格式
     * @return
     */
    public static Date stringToDate(String strDate, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        try {
            return df.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取当前年份
     *
     * @return
     */
    public static int getYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取具体日期的年份
     *
     * @return
     */
    public static int getYear(Date startDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取当前月份
     *
     * @return
     */
    public static int getMonth() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取具体日期的月份
     *
     * @return
     */
    public static int getMonth(Date startDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取day of the month
     *
     * @return day    eg the first day of month is 1
     */
    public static int getDay() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 某一天当月开始日期
     *
     * @param date
     * @return
     */
    public static Date getDayMonthBegin(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 某一天当月结束日期
     *
     * @param date
     * @return
     */
    public static Date getDayMonthEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 某天后的日期
     *
     * @param dur
     * @return
     */
    public static Date add(int dur) {
        return add(new Date(), dur);
    }

    /**
     * 具体日期某一天后的日期
     *
     * @param startDate 指定日期
     * @param dur       某天
     * @return
     */
    public static Date add(Date startDate, int dur) {
        return add(startDate, Calendar.DATE, dur);
    }

    /**
     * 具体日期以后的日期
     *
     * @param startDate
     * @param filed
     * @param dur
     * @return
     */
    public static Date add(Date startDate, int filed, int dur) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(filed, dur);
        return calendar.getTime();
    }

    /**
     * 增加分钟
     *
     * @param minutes
     * @return
     */
    public static Date addMinutes(int minutes) {
        Calendar calendar = GregorianCalendar.getInstance();
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 计算两个日期相差天数
     *
     * @param date1
     * @param date2
     * @return date2-date1天数
     */
    public static int between(Date date1, Date date2) {
        Date date1Temp = getDayBegin(date1);
        Date date2Temp = getDayBegin(date2);
        int dur = (int) ((date2Temp.getTime() - date1Temp.getTime()) / TimeConstants.DAY_IN_MILLISECONDS);
        return dur;
    }

    /**
     * 获取星期几
     *
     * @return
     */
    public static int getDayOfWeek() {
        Calendar calendar = GregorianCalendar.getInstance();
        int day_of_week = calendar.get(Calendar.DAY_OF_WEEK);
        if (day_of_week == Calendar.SUNDAY)
            return 7;
        else
            return day_of_week - 1;
    }

    /**
     * @return
     * @Author wangzhenwei
     * @create 2019/3/12
     * @Description 获取时间戳字符串
     */
    public static String getTimestampStr(Date date) {
        if (date == null) {
            return "";
        }
        try {
            Date date1 = parseDateStr("1970-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
            if (date1.getTime() > date.getTime()) {
                return "";
            }
        } catch (ParseException e) {
            return "";
        }
        return String.valueOf(date.getTime());
    }

    /**
     * @param cntDateBeg 开始时间
     * @param cntDateEnd 结束时间
     * @return
     */
    public static List<String> addDates(String cntDateBeg, String cntDateEnd) {
        List<String> list = new ArrayList<>();
        //拆分成数组
        String[] dateBegs = cntDateBeg.split("-");
        String[] dateEnds = cntDateEnd.split("-");
        //开始时间转换成时间戳
        Calendar start = Calendar.getInstance();
        start.set(Integer.valueOf(dateBegs[0]), Integer.valueOf(dateBegs[1]) - 1, Integer.valueOf(dateBegs[2]));
        Long startTIme = start.getTimeInMillis();
        //结束时间转换成时间戳
        Calendar end = Calendar.getInstance();
        end.set(Integer.valueOf(dateEnds[0]), Integer.valueOf(dateEnds[1]) - 1, Integer.valueOf(dateEnds[2]));
        Long endTime = end.getTimeInMillis();
        //定义一个一天的时间戳时长
        Long oneDay = 1000 * 60 * 60 * 24l;
        Long time = startTIme;
        //循环得出
        while (time <= endTime) {
            list.add(new SimpleDateFormat("yyyy-MM-dd").format(new Date(time)));
            time += oneDay;
        }
        return list;
    }

    public static class TimeConstants {
        //毫秒
        public static final long SECOND_IN_MILLISECONDS = 1000L;
        public static final long TEN_SECOND_IN_MILLISECONDS = 10000L;
        public static final long MINUTE_IN_MILLISECONDS = 60000L;
        public static final long TEN_MINUTE_IN_MILLISECONDS = 600000L;
        public static final long FIVE_MINUTE_IN_MILLISECONDS = 300000L;
        public static final long HALF_HOUR_IN_MILLISECONDS = 1800000L;
        public static final long HOUR_IN_MILLISECONDS = 3600000L;
        public static final long DAY_IN_MILLISECONDS = 86400000L;
        public static final long SIX_DAY_IN_MILLISECONDS = 518400000L;
        public static final long WEEK_IN_MILLISECONDS = 604800000L;
        public static final long MONTH_IN_MILLISECONDS = 2592000000L;
        public static final long YEAR_IN_MILLISECONDS = 31536000000L;
        public static final long TEN_YEAR_IN_MILLISECONDS = 315360000000L;
        //秒
        public static final int MINUTE_IN_SECONDS = 60;
        public static final int FIVE_MINUTE_IN_SECONDS = 300;
        public static final int TEN_MINUTE_IN_SECONDS = 600;
        public static final int HALF_HOUR_IN_SECONDS = 1800;
        public static final int HOUR_IN_SECONDS = 3600;
        public static final int TWO_HOUR_IN_SECONDS = 7200;
        public static final int DAY_IN_SECONDS = 86400;
        public static final int WEEK_IN_SECONDS = 604800;
        public static final int FOUR_WEEK_IN_SECONDS = 2419200;
        public static final int MONTH_IN_SECONDS = 2592000;
        public static final int YEAR_IN_SECONDS = 31536000;
        //小时
        public static final int DAY_IN_HOUR = 24;

        private TimeConstants() {
        }
    }
}
